﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;

namespace TcpServerDemo
{
    /*
    public class TcpClientState
    {
        public byte[] Buffer { get; set; }
        public TcpClient TcpClient { get; set; }
        public NetworkStream NetworkStream { get; set; }
        public TcpClientState(TcpClient tcpClient, byte[] buffer)
        {
            this.TcpClient = tcpClient;
            this.Buffer = buffer;
            this.NetworkStream = tcpClient.GetStream();
        }
    }

    public partial class Program
    {
        static List<TcpClientState> clients = [];

        static void HandleTcpClientAccepted(IAsyncResult ar)
        {
            TcpListener tcpListener = (TcpListener)ar.AsyncState;

            TcpClient tcpClient = tcpListener.EndAcceptTcpClient(ar);
            byte[] buffer = new byte[tcpClient.ReceiveBufferSize];

            TcpClientState internalClient = new TcpClientState(tcpClient, buffer);

            lock (clients)
            {
                clients.Add(internalClient);
                // RaiseClientConnected(tcpClient);
            }

            NetworkStream networkStream = internalClient.NetworkStream;

            networkStream.BeginRead(
                internalClient.Buffer,
                0,
                internalClient.Buffer.Length,
                HandleDatagramReceived,
                internalClient);

            tcpListener.BeginAcceptTcpClient(
                new AsyncCallback(HandleTcpClientAccepted), ar.AsyncState);
        }

        static void HandleDatagramReceived(IAsyncResult ar)
        {
            TcpClientState internalClient = (TcpClientState)ar.AsyncState;
            NetworkStream networkStream = internalClient.NetworkStream;
            int numberOfReadBytes = 0;
            try
            {
                numberOfReadBytes = networkStream.EndRead(ar);
            }
            catch
            {
                numberOfReadBytes = 0;
            }

            if (numberOfReadBytes == 0)
            {
                // connection has been closed
                lock (clients)
                {
                    clients.Remove(internalClient);
                    return;
                }
            }

            // received byte and trigger event notification
            byte[] receivedBytes = new byte[numberOfReadBytes];
            Buffer.BlockCopy(
                internalClient.Buffer, 0,
                receivedBytes, 0, numberOfReadBytes);
            //RaiseDatagramReceived(internalClient.TcpClient, receivedBytes);
            //RaisePlaintextReceived(internalClient.TcpClient, receivedBytes);
            string msg = Encoding.UTF8.GetString(receivedBytes, 0, receivedBytes.Length);
            Console.WriteLine("接收到消息：{0}", msg);
            GenericReceived(internalClient, "Server has received you text: " + msg);

            // continue listening for tcp datagram packets
            networkStream.BeginRead(
                internalClient.Buffer, 0, internalClient.Buffer.Length,
                HandleDatagramReceived, internalClient);
        }

        static void GenericReceived(TcpClientState client, string data)
        {
            var bytes = Encoding.UTF8.GetBytes(data);

            client.NetworkStream.BeginWrite(
                bytes, 0, bytes.Length, HandleDatagramWritten, client);
        }

        static void HandleDatagramWritten(IAsyncResult ar)
        {
            TcpClientState internalClient = (TcpClientState)ar.AsyncState;
            internalClient.NetworkStream.EndWrite(ar);
        }

        static void Main(string[] args)
        {
            var encoding = Encoding.UTF8;
            var address = IPAddress.Any;
            var port = 8181;
            var listener = new TcpListener(address, port);
            listener.Start();
            // 开始侦听客户端连接
            listener.BeginAcceptTcpClient(
                new AsyncCallback(HandleTcpClientAccepted), listener);

            Console.ReadLine();
        }
    }
    */
}
